AngularJs 学习笔记(三)
一、作用域
- 先找自己,再找父级
- 子级可以访问父级的元素
- 父级不能访问子级的元素。如果在该作用域下元素没有值,则该值为空不显示
每个控制器又都对应一个模型,也就是$scope对象,不同层级控制器下的$scope便产生了作用域
<script> var app = angular.module('app',[]); 通过ng-controller指令可以创建一个子作用域, 新建的作用域可以访问父作用域的数据 app.controller('wooController1',['$scope',function ($scope) { $scope.name = "woo1"; }]); app.controller('wooController2',['$scope',function ($scope) { $scope.name = "woo2"; }]) </script>
ng-init初始化全局变量
- 一个AngularJs的应用,在启动时会自动创建一个根作用域$rootScope,这个根作用域在整个应用范围(ng-app所在标签以内)都是可以被访问到的
- 使用ng-init=“属性名称=属性值”
使用ng-init创建的就是根作用域
<body ng-app="app" ng-init="name='init'"> <div ng-controller="wooController2"> <p>----{{name}}</p> <ul ng-controller="wooController1"> <li>{{name}}</li> </ul> </div>
二、过滤器
过滤器是用来了格式化数据用的
angular内置了9个过滤器
- currency:将数值格式化为货币格式
- date:日期格式化,年(y)、月(M)、日(d)、星期(EEEE/EEE)、时(H/h)、分(m)、秒(s)、毫秒(.sss),也可以组合到一起使用。
- filter:在给定数组中选择满足条件的一个子集,并返回一个新的数组,其条件可以是一个字符串、对象、函数
- josn:将javascript对象转成JSON字符串
- limitTo:取出字符串或数组的前(正数)几位或后(负数)几位
- lowercase:将文本转换成小写格式
- uppercase:将文本转换成大写格式
- number:数字格式化,可控制小位位数
- orderBy:对数组进行排序,第2个参数可控制方向
app.controller('wooController',['$scope',function ($scope) {
$scope.price = 20;
$scope.nowDate = new Date();
$scope.course = ['html','js','css'];
$scope.student = [{name:'zs',age:18},{name:'ls',age:20},
{name:'ww',age:10}];
$scope.str = 'hello world';
$scope.num = "10";
}])
<body ng-app="app" ng-controller="xmgController">
管道符 上次的结果当作下一次的参数进行传递
过滤器的本质是一个方法
会自动把|前面的内容,当作方法的第一个参数传入
如果想要自己手动传参 使用:来进行传递
<p>{{price|currency:'&'}}</p>
<p>{{nowDate|date:'yyyy/MM/dd h:m:s'}}</p>
<p>{{course|filter:'s'}}</p>
<p>{{student|json}}</p>
<p>{{student|limitTo:-2}}</p>
<p>{{str|uppercase|lowercase}}</p>
<p>{{student|orderBy:'age':false}}</p> true 是降序 false是升序
<p>{{num|number:2}}</p> 在num当中不能出现非数字
自定义过滤器
AngularJs内置过滤器外,还可以根据业务需要自定义过滤器
通过模块对象实例提供的filter方法自定义过滤器
<script>
var app = angular.module('app',[]);
自定义控制器
app.controller('wooController',['$scope',function ($scope) {
$scope.name = "121";
$scope.str = "hello";
}]);
自定义指令
app.directive('directiveName',[function () {
return {
};
}]);
自定义过滤器
第一个参数:过滤器的名称
第二个参数:回调函数
返回值为一个函数(input 为自动传入的数据,它为管道符前面的内容)
app.filter('filterName',[function () {
return function (input) {
console.log('hello'+ input);
}
}]);
app.filter('firstUppcase',[function () {
return function (input) {
slice:从指定的位置,截取到末尾
return input[0].toUpperCase()+input.slice(1)
};
}]);
</script>
<body ng-app="app" ng-controller="wooController">
<p>{{name|filterName}}</p>
<p>{{str|firstUppcase}}</p>
</body>
三、依赖注入
- AngularJs采用模块化的方式组织代码,将一些通用逻辑封装成一个对象或函数,实现最大程度的复用
- 这导致了使用者和被使用者之间存在依赖关系
- 所谓依赖注入是指在运行时自动查找依赖关系
- 然后将查找到依赖传递给使用者的一种机制
依赖注入分为两种:
1.行内式注入
以数组形式明确声明依赖,数组元素都是包含依赖名称的字符串,数组最后一个元素是依赖注入的目标函数
推荐使用行内式注入
2.推断式注入
没有明确声明依赖,AngularJs会将函数参数名称当成是依赖的名称
这种方式会带来一个问题,当代码经过压缩后函数的参数被压缩,这样便会造成依赖无法找到
<script>
var app = angular.module('app',[]);
自定义控制器
1.行内式注入
app.controller('wooController',
['$scope','$http',function ($scope,$http) {
$scope.name = "121";
$scope.str = "hello";
}]);
2.推断式注入
app.controller('wooController',function ($scope,$http) {
$scope.name = 'woo';
});
</script>
四、服务
服务是一个对象或函数,对外提供特定的功能
常见内置服务有:
- $location
- $timeout
- $filter
- $log
$http
同时还支持多种快捷方式如$http.get()、$http.post()、$http.json
$location服务
- $location服务解析在浏览器地址栏中的URL(基于window.location)并且让URL在你的应用中可用。
- $localtion.ablUrl() 获取绝对路径
- $localtion.protocol() 获取协议
- $localtion.port() 端口
- $localtion.path() 当前路径
- $localtion.hash 获取hash值
- $localtion.search 查询字符串
网络地址
* http:// 协议
* localhost:主机地址 www.baidu.com 139.129.256.5
* :8080 端口号
* /code/06-$location服务.html 文件路径
* # 锚点
* ?name=xmg&&age=10 传的参数
可以查看原生的网络地址
for ( var key in location) {
console.log(key +'=>'+location[key]);
}
var app = angular.module('app',[]);
app.controller('wooController',
['$scope','$location',function ($scope,$location) {
$scope.absUrl = $location.absUrl();
获取的是锚点后面的地址
$scope.url = $location.url();
端口号
$scope.port = $location.port();
主机名
$scope.host = $location.host();
获取的锚点。从第二个锚点开始的值
$scope.hash = $location.hash();
参数
$scope.search = $location.search();
}]);
<p>{{absUrl}}</p>
<p>{{url}}</p>
<p>{{port}}</p>
<p>{{host}}</p>
<p>{{hash}}</p>
<p>{{search}}</p>
$timeout和$interval服务
$timeout&$interval对原生Javascript中的setTimeout和setInterval进行了封装。
var app = angular.module('app',[]);
app.controller('wooController',
['$scope','$timeout','$interval',function ($scope,$timeout,$interva
l) {
$scope.name = 'woo';
延时执行任务
$timeout(function () {
$scope.name="xmg123";
},1000);
隔指定时间执行任务
var timer = $interval(function () {
$scope.dateTime = new Date();
},1000);
点击按钮停止定时器
$scope.stop = function () {
alert('aaa');
停止指定的定时器
$interval.cancel(timer);
}
}]);
<p>{{name}}</p>
<p>{{dateTime | date:'yyyy-MM-dd h:m:s'}}</p>
<button ng-click="stop()">停止</button>
$filter服务
- 行内式注入
- 不要在view中过多的处理业务逻辑,应该在控制器当中处理完毕后,直接显示到view
app.controller('wooController',
['$scope','$filter',function ($scope,$filter) {
$scope.price = 20;
$scope.str = "hello";
使用$filter获取9个服务中的一个
获取后再去使用获取的筛选
var currency = $filter('currency');
$scope.price = currency($scope.price);
var uppcase = $filter('uppercase');
$scope.str = uppcase($scope.str);
可以直接在后面使用
$scope.str = $filter('limitTo')($scope.str,2);
}]);
$log服务
var app = angular.module('app',[]);
app.controller('wooController',['$log',function ($log) {
$log.log('woo');
$log.info('woo');
$log.warn('woo');
$log.error('woo');
$log.debug('woo');
}]);
$http服务
var app = angular.module('app',[]);
app.controller('wooController',
['$scope','$http',function ($scope,$http) {
$http({
url: 'get.php', 请求地址
method:'get', 请求方法
params:{ get方式传递参数 在传递过程中,会自动帮你转成
get.php?name=woo
传递时->name:woo
name:'woo'
}
}).success(function (res) { 注意:这里的success和error是在angular1.5之前的,1.6是用then跟catch
alert(res); 成功时回调
}).error(function(error){
失败时回调
});
$http({
url: 'post.php', 请求地址
method:'post', 请求方法
post必须得要设置请求头
headers:{
'Content-Type':'application/x-www-formurlencoded'
},
//data:{ data:{} 传参形式 在传递数据时,是以json来传递的
name:"woo" json串
}
data:'name=woo' formdata
}).success(function (res) {
alert(res);
}).error(function (res) {
});
当设置请求头的时候为application/x-www-form-urlencoded是以soap 以对象形式传递
SOAP: 以对象形式传递
RESTFUL:json串形式进行传递
}]);
自定义服务分为三种:
1.factory
app.factory('show',function () {
return function () { 直接以方法来调用
alert("hello");
};
function show1() {
alert("show1");
逻辑
}
function show2() {
alert("show2");
}
return {
show1:show1,
show2:show2
}
});
自定义控制器
使用自己定义的服务要注入进来
app.controller('wooController',
['$scope','$http','show',function ($scope,$http,show) {
show.show1();
show.show2();
}]);
2.service
如果要依赖其他的服务,那么就把其他的服务注入进来
app.service('showTime',['$filter',function ($filter) {
里面所有的功能要使用this来定义
this.cur_date = function () {
var cur_date = new Date();
var date = $filter('date');
return date(cur_date,'yyyy-MM-dd h:m:s');
};
this.sayHello = function () {
alert("hello world");
}
}]);
service自定义服务,所有的方法都是以this的方式定义
var app = angular.module('app',[]);
同样也是要注入自定义的服务
app.controller('wooController',
['$scope','showTime',function ($scope,showTime) {
$scope.cur_date = showTime.cur_date();
调用服务
showTime.sayHello();
}]);
<body ng-app="app" ng-controller="wooController">
<h1>{{cur_date}}</h1>
3.value
- value表现形式上是一个服务
- 本质上可看做是一个常量
- 常量:其值始终保持不变的量
变量:其值可以发生改变的量
var app = angular.module('app',[]); 注入服务 app.controller('wooController', ['$scope','key','version',function ($scope,key,version) { $scope.key = key; $scope.version = version; }]); 使用服务 app.value('version','1.0’); app.value('key','woo');
五、跨域原理
1.什么是跨域?
不同域名之间进行数据的访问
2.使用jsonp
Ajax与jsonp有关系吗
jsonp与ajax是没有关系的。ajax是使用js内置的对象进行网络请求获取数据,是一种技术。jsonp是使用script当中的src来获取数据
为什么会有跨域?
为了数据的安全
是谁导致了跨域?
是浏览器。
浏览器为了保证数据的安全,不允许直接使用别的域名数据。浏览器做了一个拦截。其实数据已经响应到了浏览器。浏览器没有把它给我们
解决跨域方式:
使用script当中src方式进行数据请求
在前端定义一个function
function fn(res) { alert(res); }
通过创建一个
<script src=>
向服务器发送一个请求。src当中去请求要跨域的网络地址,src的地址当中要添加一个参数callback,并且值就是声明的方法名称<script src="get.php?callback=fn"></script>
服务器接受callback值
$fn = $_GET['callback']
在返回时,在接收参数这后面拼接一个括号。如果想要传递数据,就把数据放到括号当中。
echo $fn.'("xmg123")';
就会执行前端定义的function
fn("hello");
跨域只有前端处理,是没有办法达到效果的。必须得要结合后端一起,来去处理
使用Angular $http实现跨域
$http({
url:'',
method:'jsonp',
params:{
pin:'',
uuid: -1,
callback:'JSON_CALLBACK'
//当为jsonp时,会自动帮你添加一个script
//帮你生成一个方法(angular.callbacks._0)
}
})
使用php做桥接实现跨域
echo file_get_contents('https://xxxxxxx')